package com.codewsq.java;

import org.junit.Test;

import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.time.temporal.TemporalAccessor;
import java.util.Date;

/**
 * jdk 8中日期时间API的测试
 *
 * @author codewsq
 * @date 2021/8/5 0005 16:42
 */
public class DateTimeTest2 {

    @Test
    public void test() {
        // 使用date设置时间，需要考虑时间偏移量
        Date date = new Date(2021 - 1900, 8 - 1, 5);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String format = sdf.format(date);
        System.out.println(format);
    }


    /*
    LocalDate、LocalTime、LocalDateTime 的使用
    说明：
        1.LocalDateTime相较于LocalDate、LocalTime，使用频率要高
        2.类似于Calendar
     */
    @Test
    public void testLocalDateTime() {
        // LocalDate、LocalTime、LocalDateTime的实例化操作
        // now():获取当前的日期、时间、日期+时间
        LocalDate localDate = LocalDate.now(); // 日期
        LocalTime localTime = LocalTime.now();// 时间
        LocalDateTime localDateTime = LocalDateTime.now();// 日期 + 时间

        System.out.println(localDate);
        System.out.println(localTime);
        System.out.println(localDateTime);

        System.out.println("-------------------of()-----------------------");
        // static of():设置指定的年、月、日、时、分、秒。没有偏移量
        LocalDateTime of = LocalDateTime.of(2021, 10, 01, 10, 20, 30);
        System.out.println(of);
        System.out.println("-------------------getXxxx()-----------------------");
        // getXxxx(): 获取相关属性
        System.out.println(localDateTime.getDayOfYear()); // 一年中的第几天
        System.out.println(localDateTime.getYear()); // 几几年 ints
        System.out.println(localDateTime.getDayOfMonth()); // 一月中的第几天
        System.out.println(localDateTime.getMonth()); // 第几月 -- 返回月份枚举
        System.out.println(localDateTime.getMonthValue()); // 第几月，返回具体月份，准确的 int
        System.out.println(localDateTime.getDayOfWeek()); // 星期几，返回 星期枚举
        System.out.println(localDateTime.getDayOfWeek().getValue()); // 返回具体星期几 int
        System.out.println(localDateTime.getMinute()); // 获取分钟数

        System.out.println("-------------------体现该时间类的不可变性-----------------------------");
        // withXxx(): 对日期和时间进行调整s
        System.out.println("-------------------withXxxx()-----------------------");
        LocalDateTime localDateTime1 = localDateTime.withDayOfMonth(3); // 讲日期改为当月第三天
        System.out.println("调整前：" + localDateTime);
        System.out.println("调整后：" + localDateTime1);

        LocalDateTime localDateTime2 = localDateTime.withHour(4); // 将时间改为4点
        System.out.println("时间设置为4点：" + localDateTime2);


        // 加3个月减4天
        // plusXxxx(long time)：在基础上添加
        // minusXxx(long time)：在基础上减去
        LocalDateTime localDateTime3 = localDateTime.plusMonths(3).minusDays(4);
        System.out.println("加3个月减4天:" + localDateTime3);

    }

    /*
    *Instant的使用
    类似于 java.util.Date类
    *
    * */
    @Test
    public void testInstant() {
        // now():获取本初子午线对应的标准时间, 比北京时间早8小时
        Instant instant = Instant.now();
        System.out.println(instant);

        // 添加时间的偏移量，偏移8小时，就是当前时间
        OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));
        System.out.println(offsetDateTime);

        //toEpochMilli():获取自1970年1月1日0时0分0秒（UTC）开始的毫秒数  ---> Date类的getTime()
        long toEpochMilli = instant.toEpochMilli();
        System.out.println(toEpochMilli);

        //ofEpochMilli():通过给定的毫秒数，获取Instant实例  等同于Date(long millis)
        Instant ofEpochMilli = Instant.ofEpochMilli(1550475314878L);
        System.out.println(ofEpochMilli);
    }

    /*
    *
    * DateTimeFormatter:格式化或解析日期、时间
    类似于SimpleDateFormat
    *
    * */
    @Test
    public void testDateTimeFormat() {
        // 方式一：预定义的标准格式。如：ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
        DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;

        // 格式化： 日期->字符
        LocalDateTime localDateTime = LocalDateTime.now();
        String format = formatter.format(localDateTime);
        System.out.println(format); // 2021-08-13T16:04:51.015

        // 解析： 字符串->日期 TemporalAccessor是LocalDateTime的父类接口,
        //       LocalDateTime实现了Temporal接口，Temporal继承了TemporalAccessor接口
        TemporalAccessor temporalAccessor = formatter.parse("2021-08-13T16:04:51.015");
        System.out.println(temporalAccessor);

        System.out.println("-----------------------------方式二：本地枚举定义的格式化方式----------------------------------");

        // 方式二：
        // 本地化相关的格式。如：ofLocalizedDateTime()
        // FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT :适用于LocalDateTime
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);
        // 格式化
        String str = dateTimeFormatter.format(LocalDateTime.now());
        System.out.println("FormatStyle.LONG: " + str);
        System.out.println("FormatStyle.MEDIUM: " + DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).format(LocalDateTime.now()));
        System.out.println("FormatStyle.SHORT: " + DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).format(LocalDateTime.now()));

        // 本地化相关的格式。如：ofLocalizedDate()
        // FormatStyle.FULL / FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT : 适用于LocalDate
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
        str = dateFormatter.format(LocalDate.now());
        System.out.println("ofLocalizedDate() --> FormatStyle.FULL: " + str);

        System.out.println("-----------------------------方式三：自定义格式（重点）----------------------------------");

        // 重点： 方式三：自定义的格式。如：ofPattern(“yyyy-MM-dd HH:mm:ss”)
        // 新发现：自定义时间格式时，小时的格式:
        //              hh-12小时制：使用12小时制的解析12小时以上的时间会出现异常，
        //                          如-->java.time.format.DateTimeParseException:
        //                              Text '2020-12-20 17:40:40' could not be parsed: Invalid value for ClockHourOfAmPms
        //              HH-24小时制
        DateTimeFormatter ofPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 格式化
        String str2 = ofPattern.format(LocalDateTime.now());
        System.out.println(str2);

        // 解析
        TemporalAccessor parse = ofPattern.parse("2020-12-20 19:40:09");
        System.out.println(parse);
        System.out.println(parse.getClass());
    }
}
